﻿
namespace ShoppingCart.DataAccess
{
    using System;
    using System.Data;
    using Microsoft.Practices.EnterpriseLibrary.Data;
    using ShoppingCart.Business.Entity;
    using ShoppingCart.Business.Entity.Collections;

	/// <summary>
	/// Represents the DataAccess of CuentaData.
	/// </summary>
	public class CuentaData : Singleton<CuentaData>
	{
		#region Attributes

		private readonly Database BaseDatos = DatabaseFactory.CreateDatabase();

		#endregion

		#region Methods

		/// <summary>
		/// Selects all records from the Cuenta table by a foreign key.
		/// </summary>
		public Cuenta Obtener(int idCuenta)
		{
			var cuenta = default(Cuenta);
			var comando = BaseDatos.GetStoredProcCommand("SelectCuenta");

			BaseDatos.AddInParameter(comando, "IdCuenta", DbType.Int32, idCuenta);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
					cuenta = new Cuenta
					{
						IdCuenta = lector.GetInt32(lector.GetOrdinal("IdCuenta")),
						Numero = lector.GetString(lector.GetOrdinal("Numero")),
                        Tipo = lector.GetByte(lector.GetOrdinal("Tipo")),
                        Banco = BancoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdBanco")))
					};
				}
			}
			comando.Dispose();
			return cuenta;
		}

		/// <summary>
		/// Saves a record to the Cuenta table.
		/// </summary>
		public int Agregar(Cuenta cuenta)
		{
			var comando = BaseDatos.GetStoredProcCommand("InsertCuenta");
			BaseDatos.AddOutParameter(comando, "IdCuenta", DbType.Int32, 4);
			BaseDatos.AddInParameter(comando, "IdBanco", DbType.Int32, cuenta.Banco.IdBanco);
			BaseDatos.AddInParameter(comando, "Numero", DbType.String, cuenta.Numero);
			BaseDatos.AddInParameter(comando, "Tipo", DbType.Byte, cuenta.Tipo);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Agregar Cuenta.");

			var valorDevuelto = (int)BaseDatos.GetParameterValue(comando, "IdCuenta");;
			comando.Dispose();
			return valorDevuelto;
		}

		/// <summary>
		/// Updates a record in the Cuenta table.
		/// </summary>
		public bool Modificar(Cuenta cuenta)
		{
			var comando = BaseDatos.GetStoredProcCommand("UpdateCuenta");
			BaseDatos.AddInParameter(comando, "IdCuenta", DbType.Int32, cuenta.IdCuenta);
			BaseDatos.AddInParameter(comando, "IdBanco", DbType.Int32, cuenta.Banco.IdBanco);
			BaseDatos.AddInParameter(comando, "Numero", DbType.String, cuenta.Numero);
			BaseDatos.AddInParameter(comando, "Tipo", DbType.Byte, cuenta.Tipo);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Modificar Cuenta.");

			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Cuenta table by its primary key.
		/// </summary>
		public bool Eliminar(int idCuenta)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteCuenta");
			BaseDatos.AddInParameter(comando, "IdCuenta", DbType.Int32, idCuenta);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Cuenta.");
			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Cuenta table by a foreign key.
		/// </summary>
		public void EliminarPorIdBanco(int idBanco)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteCuentaByIdBanco");
			BaseDatos.AddInParameter(comando, "IdBanco", DbType.Int32, idBanco);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Cuenta.");
			comando.Dispose();
		}

		/// <summary>
		/// Selects all records from the Cuenta table by a foreign key.
		/// </summary>
		public CuentaCollection ListarPorIdBanco(int idBanco)
		{
			var entidades = new CuentaCollection();
			var comando = BaseDatos.GetStoredProcCommand("SelectCuentaByIdBanco");

			BaseDatos.AddInParameter(comando, "IdBanco", DbType.Int32, idBanco);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    entidades.Add(new Cuenta
                    {
                        IdCuenta = lector.GetInt32(lector.GetOrdinal("IdCuenta")),
                        Numero = lector.GetString(lector.GetOrdinal("Numero")),
                        Tipo = lector.GetByte(lector.GetOrdinal("Tipo")),
                        Banco = new Banco { IdBanco = idBanco }
                    });
				}
			}
			comando.Dispose();
			return entidades;
		}

		#endregion
	}
}
